home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_query.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.1 KB  |  544 lines

  1. #include <stdio.h>
  2. #include "dwarf_incl.h"
  3. #include "dwarf_die_deliv.h"
  4.  
  5.  
  6. int
  7. dwarf_dieoffset (
  8.     Dwarf_Die       die,
  9.     Dwarf_Off      *ret_offset,
  10.     Dwarf_Error     *error
  11. )
  12. {
  13.     CHECK_DIE(die, DW_DLV_ERROR)
  14.  
  15.     *ret_offset = (die->di_debug_info_ptr - 
  16.     die->di_cu_context->cc_dbg->de_debug_info);
  17.     return DW_DLV_OK;
  18. }
  19.  
  20.  
  21. /*
  22.     This function returns the offset of
  23.     the die relative to the start of its
  24.     compilation-unit rather than .debug_info.
  25.     Returns DW_DLV_ERROR on error.
  26. */
  27. int
  28. dwarf_die_CU_offset (
  29.     Dwarf_Die        die,
  30.     Dwarf_Off       *cu_off,
  31.     Dwarf_Error        *error
  32. )
  33. {
  34.     Dwarf_CU_Context    cu_context;
  35.  
  36.     CHECK_DIE(die, DW_DLV_ERROR)
  37.     cu_context = die->di_cu_context;
  38.  
  39.     *cu_off = (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info -
  40.     cu_context->cc_debug_info_offset);
  41.     return DW_DLV_OK;
  42. }
  43.  
  44.  
  45. int
  46. dwarf_tag (
  47.     Dwarf_Die       die,
  48.     Dwarf_Half      *tag,
  49.     Dwarf_Error     *error
  50. )
  51. {
  52.     CHECK_DIE(die, DW_DLV_ERROR)
  53.  
  54.   
  55.     *tag =(die->di_abbrev_list->ab_tag);
  56.     return DW_DLV_OK;
  57. }
  58.  
  59.  
  60. int
  61. dwarf_attrlist (
  62.     Dwarf_Die         die,
  63.     Dwarf_Attribute   **attrbuf,
  64.     Dwarf_Signed      *attrcnt,
  65.     Dwarf_Error       *error
  66. )
  67. {
  68.     Dwarf_Word              attr_count = 0;
  69.     Dwarf_Word                i;
  70.     Dwarf_Half              attr;
  71.     Dwarf_Half            attr_form;
  72.     Dwarf_Byte_Ptr          abbrev_ptr;
  73.     Dwarf_Abbrev_List        abbrev_list;
  74.     Dwarf_Attribute        new_attr;
  75.     Dwarf_Attribute        head_attr = NULL, curr_attr;
  76.     Dwarf_Attribute        *attr_ptr;
  77.     Dwarf_Debug            dbg;
  78.     Dwarf_Byte_Ptr        info_ptr;
  79.  
  80.     CHECK_DIE(die, DW_DLV_ERROR)
  81.     dbg = die->di_cu_context->cc_dbg;
  82.  
  83.     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, 
  84.     die->di_abbrev_list->ab_code);
  85.     if (abbrev_list == NULL) {
  86.     _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD); 
  87.     return(DW_DLV_ERROR);
  88.     }
  89.     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
  90.  
  91.     info_ptr = die->di_debug_info_ptr;
  92.     SKIP_LEB128_WORD(info_ptr)
  93.  
  94.     do {
  95.         DECODE_LEB128_UWORD(abbrev_ptr, attr)
  96.         DECODE_LEB128_UWORD(abbrev_ptr, attr_form)
  97.  
  98.     if (attr != 0) {
  99.             new_attr = (Dwarf_Attribute)_dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
  100.         if (new_attr == NULL) {
  101.             _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  102.             return(DW_DLV_ERROR);
  103.         }
  104.  
  105.         new_attr->ar_attribute = attr;
  106.         new_attr->ar_attribute_form = attr_form;
  107.         new_attr->ar_cu_context = die->di_cu_context;
  108.         new_attr->ar_debug_info_ptr = info_ptr;
  109.  
  110.         info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr);
  111.  
  112.         if (head_attr == NULL)
  113.             head_attr = curr_attr = new_attr;
  114.         else {
  115.             curr_attr->ar_next = new_attr;
  116.             curr_attr = new_attr;
  117.         }
  118.             attr_count++;
  119.     }
  120.     } while (attr != 0 || attr_form != 0);
  121.  
  122.     if (attr_count == 0) {
  123.     *attrbuf = NULL;
  124.     *attrcnt = 0;
  125.     return(DW_DLV_NO_ENTRY);
  126.     }
  127.  
  128.     attr_ptr = (Dwarf_Attribute *)
  129.     _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
  130.     if (attr_ptr == NULL) {
  131.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  132.     return(DW_DLV_ERROR);
  133.     }
  134.  
  135.     curr_attr = head_attr;
  136.     for (i = 0; i < attr_count; i++) {
  137.     *(attr_ptr + i) = curr_attr;
  138.     curr_attr = curr_attr->ar_next;
  139.     }
  140.  
  141.     *attrbuf = attr_ptr;
  142.     *attrcnt = attr_count;
  143.     return(DW_DLV_OK);
  144. }
  145.  
  146.  
  147. /*
  148.     This function takes a die, and an attr, and returns
  149.     a pointer to the start of the value of that attr in
  150.     the given die in the .debug_info section.  The form
  151.     is returned in *attr_form.
  152.  
  153.     Returns NULL on error, or if attr is not found.
  154.     However, *attr_form is 0 on error, and positive 
  155.     otherwise.
  156. */
  157. static Dwarf_Byte_Ptr
  158. _dwarf_get_value_ptr (
  159.     Dwarf_Die        die,
  160.     Dwarf_Half        attr,
  161.     Dwarf_Half        *attr_form
  162. )
  163. {
  164.     Dwarf_Byte_Ptr          abbrev_ptr;
  165.     Dwarf_Abbrev_List        abbrev_list;
  166.     Dwarf_Half                curr_attr;
  167.     Dwarf_Half                curr_attr_form;
  168.     Dwarf_Byte_Ptr        info_ptr;
  169.  
  170.     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, 
  171.     die->di_abbrev_list->ab_code);
  172.     if (abbrev_list == NULL) {
  173.     *attr_form = 0;
  174.     return(NULL);
  175.     }
  176.     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
  177.  
  178.     info_ptr = die->di_debug_info_ptr;
  179.     SKIP_LEB128_WORD(info_ptr)
  180.  
  181.     do {
  182.         DECODE_LEB128_UWORD(abbrev_ptr, curr_attr)
  183.     DECODE_LEB128_UWORD(abbrev_ptr, curr_attr_form)
  184.  
  185.         if (curr_attr == attr) {
  186.         *attr_form = curr_attr_form;
  187.         return(info_ptr);
  188.     }
  189.  
  190.         info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg, 
  191.             curr_attr_form, info_ptr);
  192.     } while (curr_attr != 0 || curr_attr_form != 0);
  193.  
  194.     *attr_form = 1;
  195.     return(NULL);
  196. }
  197.  
  198.  
  199. int
  200. dwarf_diename (
  201.     Dwarf_Die       die,
  202.     char     **     ret_name,
  203.     Dwarf_Error     *error
  204. )
  205. {
  206.     Dwarf_Byte_Ptr          abbrev_ptr;
  207.     Dwarf_Half                attr;
  208.     Dwarf_Half                attr_form;
  209.     Dwarf_Debug            dbg;
  210.     Dwarf_Byte_Ptr        info_ptr;
  211.     Dwarf_Unsigned          string_offset;
  212.  
  213.     CHECK_DIE(die, DW_DLV_ERROR)
  214.  
  215.     info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
  216.     if (info_ptr == NULL) {
  217.     if (attr_form == 0)  {
  218.         _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  219.         return(DW_DLV_ERROR);
  220.     }
  221.     return DW_DLV_NO_ENTRY;
  222.     }
  223.  
  224.     if (attr_form == DW_FORM_string){
  225.      *ret_name =(info_ptr);
  226.      return DW_DLV_OK;
  227.     }
  228.  
  229.     dbg = die->di_cu_context->cc_dbg;
  230.     if (attr_form != DW_FORM_strp) {
  231.     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
  232.     return(DW_DLV_ERROR);
  233.     }
  234.  
  235.     READ_UNALIGNED(string_offset, info_ptr, dbg->de_length_size);
  236.  
  237.     if (dbg->de_debug_str == NULL) {
  238.     _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_NULL); 
  239.     return(DW_DLV_ERROR);
  240.     }
  241.  
  242.     if (string_offset >= dbg->de_debug_str_size) {
  243.     _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD); 
  244.     return(DW_DLV_ERROR);
  245.     }
  246.  
  247.     *ret_name = (dbg->de_debug_str + string_offset);
  248.     return DW_DLV_OK;
  249. }
  250.  
  251.  
  252. int
  253. dwarf_hasattr (
  254.     Dwarf_Die       die,
  255.     Dwarf_Half      attr,
  256.     Dwarf_Bool      *return_bool,
  257.     Dwarf_Error     *error
  258. )
  259. {
  260.     Dwarf_Half            attr_form;
  261.  
  262.     CHECK_DIE(die, DW_DLV_ERROR)
  263.  
  264.     if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
  265.     if (attr_form == 0)  {
  266.         _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  267.         return(DW_DLV_ERROR);
  268.     }
  269.         *return_bool = false;
  270.     return DW_DLV_OK;
  271.     }
  272.  
  273.     *return_bool = (true);
  274.     return DW_DLV_OK;
  275. }
  276.  
  277.  
  278. int
  279. dwarf_attr (
  280.     Dwarf_Die       die,
  281.     Dwarf_Half      attr,
  282.     Dwarf_Attribute *    ret_attr,
  283.     Dwarf_Error     *error
  284. )
  285. {
  286.     Dwarf_Half              attr_form;
  287.     Dwarf_Attribute         attrib;
  288.     Dwarf_Byte_Ptr        info_ptr;
  289.     Dwarf_Debug            dbg;
  290.  
  291.     CHECK_DIE(die, DW_DLV_ERROR)
  292.     dbg = die->di_cu_context->cc_dbg;
  293.  
  294.     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
  295.     if (info_ptr == NULL) {
  296.     if (attr_form == 0) {
  297.         _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 
  298.             return(DW_DLV_ERROR);
  299.     }
  300.     return DW_DLV_NO_ENTRY;
  301.     }
  302.  
  303.     attrib = (Dwarf_Attribute)_dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
  304.     if (attrib == NULL) {
  305.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  306.     return(DW_DLV_ERROR);
  307.     }
  308.  
  309.     attrib->ar_attribute = attr;
  310.     attrib->ar_attribute_form = attr_form;
  311.     attrib->ar_cu_context = die->di_cu_context;
  312.     attrib->ar_debug_info_ptr = info_ptr;
  313.     *ret_attr = (attrib);
  314.     return DW_DLV_OK;
  315. }
  316.  
  317.  
  318. int
  319. dwarf_lowpc (
  320.     Dwarf_Die        die,
  321.     Dwarf_Addr    *return_addr,
  322.     Dwarf_Error        *error
  323. )
  324. {
  325.     Dwarf_Addr        ret_addr;
  326.     Dwarf_Byte_Ptr    info_ptr;
  327.     Dwarf_Half        attr_form;
  328.  
  329.     CHECK_DIE(die, DW_DLV_ERROR)
  330.  
  331.     info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
  332.     if ((info_ptr == NULL && attr_form == 0) ||
  333.     (info_ptr != NULL && attr_form != DW_FORM_addr)) {
  334.     _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  335.     return(DW_DLV_ERROR);
  336.     }
  337.     if (info_ptr == NULL) {
  338.     return(DW_DLV_NO_ENTRY);
  339.     }
  340.  
  341.     READ_UNALIGNED(ret_addr, info_ptr, \
  342.     die->di_cu_context->cc_dbg->de_length_size);
  343.  
  344.     *return_addr = ret_addr;
  345.     return(DW_DLV_OK);
  346. }
  347.  
  348.  
  349. int
  350. dwarf_highpc (
  351.     Dwarf_Die        die,
  352.     Dwarf_Addr    *return_addr,
  353.     Dwarf_Error        *error
  354. )
  355. {
  356.     Dwarf_Addr        ret_addr;
  357.     Dwarf_Byte_Ptr    info_ptr;
  358.     Dwarf_Half        attr_form;
  359.  
  360.     CHECK_DIE(die, DW_DLV_ERROR)
  361.  
  362.     info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
  363.     if ((info_ptr == NULL && attr_form == 0) ||
  364.     (info_ptr != NULL && attr_form != DW_FORM_addr)) {
  365.     _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  366.     return(DW_DLV_ERROR);
  367.     }
  368.     if (info_ptr == NULL) {
  369.     return(DW_DLV_NO_ENTRY);
  370.     }
  371.  
  372.     READ_UNALIGNED(ret_addr, info_ptr, \
  373.     die->di_cu_context->cc_dbg->de_length_size);
  374.  
  375.     *return_addr = ret_addr;
  376.     return(DW_DLV_OK);
  377. }
  378.  
  379.  
  380. /*
  381.     Takes a die, an attribute attr, and checks if attr 
  382.     occurs in die.  Attr is required to be an attribute
  383.     whose form is in the "constant" class.  If attr occurs 
  384.     in die, the value is returned.  
  385.   Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
  386.     appropriate. Sets the value thru the pointer return_val.
  387.     This function is meant to do all the 
  388.     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, 
  389.     and dwarf_srclang.
  390. */
  391. static int
  392. _dwarf_die_attr_unsigned_constant (
  393.     Dwarf_Die        die,
  394.     Dwarf_Half        attr,
  395.     Dwarf_Unsigned      *return_val,
  396.     Dwarf_Error        *error
  397. )
  398. {
  399.     Dwarf_Byte_Ptr    info_ptr;
  400.     Dwarf_Half        attr_form;
  401.     Dwarf_Unsigned    ret_value;
  402.  
  403.     CHECK_DIE(die, DW_DLV_ERROR)
  404.  
  405.     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
  406.     if (info_ptr != NULL) {
  407.         switch (attr_form) {
  408.  
  409.         case DW_FORM_data1 :
  410.             *return_val =  (*(Dwarf_Small *)info_ptr);
  411.             return(DW_DLV_OK);
  412.  
  413.         case DW_FORM_data2 : 
  414.             READ_UNALIGNED(ret_value, info_ptr, sizeof(Dwarf_Shalf));
  415.         *return_val = ret_value;
  416.             return(DW_DLV_OK);
  417.  
  418.         case DW_FORM_data4 : 
  419.             READ_UNALIGNED(ret_value, info_ptr, sizeof(Dwarf_Sword));
  420.         *return_val = ret_value;
  421.             return(DW_DLV_OK);
  422.  
  423.         case DW_FORM_data8 :
  424.             READ_UNALIGNED(ret_value, info_ptr, sizeof(Dwarf_Unsigned));
  425.         *return_val = ret_value;
  426.             return(DW_DLV_OK);
  427.  
  428.         case DW_FORM_udata :
  429.             *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
  430.             return(DW_DLV_OK);
  431.  
  432.         default :
  433.         _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  434.         return(DW_DLV_ERROR);
  435.         }
  436.     }
  437.     if (attr_form == 0) {
  438.         _dwarf_error(die->di_cu_context->cc_dbg, error, DW_DLE_DIE_BAD);
  439.          return(DW_DLV_ERROR);
  440.     }
  441.     return DW_DLV_NO_ENTRY;
  442. }
  443.  
  444.  
  445. int
  446. dwarf_bytesize (
  447.     Dwarf_Die        die,
  448.     Dwarf_Unsigned    * ret_size,
  449.     Dwarf_Error        *error
  450. )
  451. {
  452.    Dwarf_Unsigned luns;
  453.    int res=_dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,&luns,error);
  454.    *ret_size = luns;
  455.    return res;
  456. }
  457.  
  458.  
  459. int
  460. dwarf_bitsize (
  461.     Dwarf_Die        die,
  462.     Dwarf_Unsigned     *ret_size,
  463.     Dwarf_Error        *error
  464. )
  465. {
  466.    Dwarf_Unsigned luns;
  467.    int res;
  468.     res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,&luns, error);
  469.     *ret_size = luns;
  470.    return res;
  471. }
  472.  
  473.  
  474. int
  475. dwarf_bitoffset (
  476.     Dwarf_Die        die,
  477.     Dwarf_Unsigned     *ret_size,
  478.     Dwarf_Error        *error
  479. )
  480. {
  481.    Dwarf_Unsigned luns;
  482.    int res;
  483.     res= _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset,&luns, error);
  484.     *ret_size = luns;
  485.    return res;
  486. }
  487.  
  488.  
  489. /* Refer section 3.1, page 21 in Dwarf Definition. */
  490. int
  491. dwarf_srclang (
  492.     Dwarf_Die        die,
  493.     Dwarf_Unsigned     *ret_size,
  494.     Dwarf_Error        *error
  495. )
  496. {
  497.    Dwarf_Unsigned luns;
  498.    int res;
  499.     res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,&luns, error);
  500.     *ret_size = luns;
  501.     return res;
  502. }
  503.  
  504.  
  505. /* Refer section 5.4, page 37 in Dwarf Definition. */
  506. int
  507. dwarf_arrayorder (
  508.     Dwarf_Die        die,
  509.     Dwarf_Unsigned     *ret_size,
  510.     Dwarf_Error        *error
  511. )
  512. {
  513.    Dwarf_Unsigned luns;
  514.     int res;
  515.     res =_dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,&luns, error);
  516.     *ret_size = luns;
  517.     return res;
  518. }
  519.  
  520. /*
  521.     Return DW_DLV_OK if ok
  522.     DW_DLV_ERROR if failure.
  523.  
  524.     If the die and the attr are not related the result is
  525.     meaningless.
  526. */
  527. int
  528. dwarf_attr_offset (
  529.     Dwarf_Die       die,
  530.     Dwarf_Attribute attr,
  531.     Dwarf_Off  *    offset, /* return offset thru this ptr */
  532.     Dwarf_Error     *error
  533. )
  534. {
  535.     Dwarf_Off attroff;
  536.     CHECK_DIE(die, DW_DLV_ERROR)
  537.  
  538.     attroff = (attr->ar_debug_info_ptr - 
  539.         die->di_cu_context->cc_dbg->de_debug_info);
  540.     *offset = attroff;
  541.     return DW_DLV_OK;
  542. }
  543.  
  544.